﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SonarSnitch.Business.Entity;
using SonarSnitch.Business.Process;
using System.Configuration;

namespace SonarSnitch
{
    public partial class frmPrincipal : Form
    {
        public frmPrincipal()
        {
            InitializeComponent();

            InicializaFiltros();

            this.Qualidade.HeaderCell.Style.BackColor = System.Drawing.Color.LightBlue;
            this.Qualidade.DefaultCellStyle.Format = "F2";
            this.Qualidade.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.Testes.HeaderCell.Style.BackColor = System.Drawing.Color.GreenYellow;
            this.Testes.DefaultCellStyle.Format = "F2";
            this.Testes.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.CoberturaResumida.HeaderCell.Style.BackColor = System.Drawing.Color.GreenYellow;
            this.CoberturaResumida.DefaultCellStyle.Format = "F2";
            this.CoberturaResumida.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.ViolacoesResumida.HeaderCell.Style.BackColor = System.Drawing.Color.LightGoldenrodYellow;
            this.ViolacoesResumida.DefaultCellStyle.Format = "F2";
            this.ViolacoesResumida.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.CoberturaDetalhada.HeaderCell.Style.BackColor = System.Drawing.Color.GreenYellow;
            this.CoberturaDetalhada.DefaultCellStyle.Format = "F2";
            this.CoberturaDetalhada.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.SucessoTestes.HeaderCell.Style.BackColor = System.Drawing.Color.GreenYellow;
            this.SucessoTestes.DefaultCellStyle.Format = "F2";
            this.SucessoTestes.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.ViolacoesDetalhada.HeaderCell.Style.BackColor = System.Drawing.Color.LightGoldenrodYellow;
            this.ViolacoesDetalhada.DefaultCellStyle.Format = "F2";
            this.ViolacoesDetalhada.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.ConformidadeRegras.HeaderCell.Style.BackColor = System.Drawing.Color.LightGoldenrodYellow;
            this.ConformidadeRegras.DefaultCellStyle.Format = "F2";
            this.ConformidadeRegras.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.ViolacoesBlockerCritical.HeaderCell.Style.BackColor = System.Drawing.Color.LightGoldenrodYellow;
            this.ViolacoesBlockerCritical.DefaultCellStyle.Format = "F2";
            this.ViolacoesBlockerCritical.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.Comentarios.HeaderCell.Style.BackColor = System.Drawing.Color.LightGoldenrodYellow;
            this.Comentarios.DefaultCellStyle.Format = "F2";
            this.Comentarios.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.CodigoDuplicado.HeaderCell.Style.BackColor = System.Drawing.Color.LightGoldenrodYellow;
            this.CodigoDuplicado.DefaultCellStyle.Format = "F2";
            this.CodigoDuplicado.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.Peso.HeaderCell.Style.BackColor = System.Drawing.Color.LightGoldenrodYellow;
            this.Peso.DefaultCellStyle.Format = "F2";
            this.Peso.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.Linhas.HeaderCell.Style.BackColor = System.Drawing.Color.LightGoldenrodYellow;
            this.Fonte.DefaultCellStyle.Format = "F2";
            this.Fonte.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.Fonte.HeaderCell.Style.BackColor = System.Drawing.Color.LightGoldenrodYellow;
            this.Linhas.DefaultCellStyle.Format = "F2";
            this.Linhas.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.Arquitetura.DefaultCellStyle.Format = "F2";
            this.Arquitetura.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.Projeto.DefaultCellStyle.Format = "F2";
            this.Projeto.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;

        }

        private static Dictionary<string, string> filtros;

        private void InicializaFiltros()
        {
            if (!string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["filtros_label"]))
            {
                var labels = ConfigurationManager.AppSettings["filtros_label"].Split(',');
                var valores = ConfigurationManager.AppSettings["filtros_valor"].Split(',');
                filtros = new Dictionary<string, string>();

                for (int i = 0; i < labels.Length; i++)
                {
                    this.chkRegional.Items.Add(new ListViewItem(labels[i]));
                    filtros.Add(labels[i], valores[i]);
                }
            }

            if (!string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["filtros_legenda"]))
            {
                this.gbFiltros.Text = ConfigurationManager.AppSettings["filtros_legenda"];
            }

            if (!string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["agrupador_botao"]))
            {
                this.cbAgrupar.Text = ConfigurationManager.AppSettings["agrupador_botao"];
            }
            
        }

        public static IList<Projeto> Projetos;
        public static List<AvaliacaoProjeto> ProjetosFiltrados = new List<AvaliacaoProjeto>();
        public static List<AvaliacaoGrupo> ProjetosAgrupados = new List<AvaliacaoGrupo>();

        private void frmPrincipal_Load(object sender, EventArgs e)
        {
            SonarService sonar = new SonarService();
            Projetos = sonar.ListarProjetos();
            foreach (var projeto in Projetos)
            {
                ProjetosFiltrados.Add(new AvaliacaoProjeto(projeto));
            }

            dtInicio.Value = dtInicio.Value.AddMonths(-1);

            CarregarGrid();
        }

        private void CarregarGrid()
        {
            gvProjetos.ClearSelection();

            this.CoberturaResumida.Visible = rbResumida.Checked;
            this.ViolacoesResumida.Visible = rbResumida.Checked;
            this.Fonte.Visible = rbDetalhada.Checked;
            this.Testes.Visible = rbDetalhada.Checked;
            this.CoberturaDetalhada.Visible = rbDetalhada.Checked;
            this.SucessoTestes.Visible = rbDetalhada.Checked;
            this.ViolacoesDetalhada.Visible = rbDetalhada.Checked;
            this.ConformidadeRegras.Visible = rbDetalhada.Checked;
            this.ViolacoesBlockerCritical.Visible = rbDetalhada.Checked;
            this.Comentarios.Visible = rbDetalhada.Checked;
            this.CodigoDuplicado.Visible = rbDetalhada.Checked;
            this.Linhas.Visible = rbDetalhada.Checked;
            this.Peso.Visible = rbDetalhada.Checked;

            if (cbAgrupar.Checked)
            {
                gvProjetos.DataSource = ProjetosAgrupados.ToList();
            }
            else
            {
                gvProjetos.DataSource = ProjetosFiltrados.ToList();
            }
            gvProjetos.Refresh();
        }

        private string IdentificaFiltro(string filtro)
        {
            return filtros[filtro];
        }

        private void FiltraProjetosPorRegional()
        {
            gbProjetos.Text = "Visão Atual";

            ProjetosFiltrados.Clear();
            string parametro = ConfigurationManager.AppSettings["filtros"];
            if (!string.IsNullOrWhiteSpace(parametro))
            {
                foreach (ListViewItem regional in chkRegional.CheckedItems)
                {
                    var filtro = IdentificaFiltro(regional.Text.Trim());
                    var filtrados = Projetos;
                    if (!string.IsNullOrWhiteSpace(filtro))
                    {
                        filtrados = filtrados.Where(p => p.Filtros[parametro] == filtro).ToList();
                    }
                    foreach (var projeto in filtrados)
                    {
                        projeto.Intervalos.Clear();
                        ProjetosFiltrados.Add(new AvaliacaoProjeto(projeto));
                    }
                }
            }
            else
            {
                foreach (var projeto in Projetos)
                {
                    projeto.Intervalos.Clear();
                    ProjetosFiltrados.Add(new AvaliacaoProjeto(projeto));
                }
            }

            AgruparProjetosPorRegional();
        }

        private void btMetricas_Click(object sender, EventArgs e)
        {
            gbProjetos.Text = "Visão de Evolução no Período";

             Parallel.ForEach<AvaliacaoProjeto>(ProjetosFiltrados, ap => { ap = CarregarAvaliacaoProjeto(ap.Projeto); });

            //for (int i = 0; i < ProjetosFiltrados.Count; i++)
            //{
            //    var projetoFiltrado = sonar.CarregarMetricasPorTempo(ProjetosFiltrados[i].Projeto, dtInicio.Value, dtTermino.Value);
            //    if (projetoFiltrado.ExisteMedicao())
            //    {
            //        ProjetosFiltrados[i] = new AvaliacaoProjeto(projetoFiltrado);
            //    }
            //    else
            //    {
            //        ProjetosFiltrados[i] = null;
            //    }
            //}

            ProjetosFiltrados.RemoveAll(p => p == null);

            CarregarGrid();

            MessageBox.Show("Projetos processados com sucesso.");
        }

        private AvaliacaoProjeto CarregarAvaliacaoProjeto(Projeto projeto)
        {
            SonarService sonar = new SonarService();
            var projetoFiltrado = sonar.CarregarMetricasPorTempo(projeto, dtInicio.Value, dtTermino.Value);
            if (projetoFiltrado.ExisteMedicao())
            {
                return new AvaliacaoProjeto(projetoFiltrado);
            }
            else
            {
                return null;
            }
        }

        string lastColum, lastDirection = string.Empty;

        private void gvProjetos_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (lastColum != gvProjetos.Columns[e.ColumnIndex].HeaderText)
            {
                ReordenaGrid(gvProjetos.Columns[e.ColumnIndex], "ASC");
                lastColum = gvProjetos.Columns[e.ColumnIndex].HeaderText;
                lastDirection = "ASC";
            }
            else
            {
                if (lastDirection != "ASC")
                {
                    ReordenaGrid(gvProjetos.Columns[e.ColumnIndex], "ASC");
                    lastDirection = "ASC";
                }
                else
                {
                    ReordenaGrid(gvProjetos.Columns[e.ColumnIndex], "DESC");
                    lastDirection = "DESC";
                }
            }
        }

        private void ReordenaGrid(DataGridViewColumn coluna, string direcao)
        {

            if (direcao.Equals("ASC"))
            {
                switch (coluna.DataPropertyName)
                {
                    case "Codigo": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.Codigo).ToList(); break;
                    case "Nome": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.Nome).ToList(); break;
                    case "Regional": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.Regional).ToList(); break;
                    case "Linhas": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.Linhas).ToList(); break;
                    case "Qualidade": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.Qualidade).ToList(); break;
                    case "ConformidadeRegras": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.ConformidadeRegras).ToList(); break;
                    case "Cobertura": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.Cobertura).ToList(); break;
                    case "Violacoes": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.Violacoes).ToList(); break;
                    case "CodigoDuplicado": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.CodigoDuplicado).ToList(); break;
                    case "DebitoTecnico": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.DebitoTecnico).ToList(); break;
                    case "Comentarios": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.Comentarios).ToList(); break;
                    case "SucessoTestes": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.SucessoTestes).ToList(); break;
                    case "ViolacoesBlockerCritical": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.ViolacoesBlockerCritical).ToList(); break;
                    case "Arquitetura": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.Arquitetura).ToList(); break;
                    case "Design": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.Design).ToList(); break;
                    case "Fonte": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.Fonte).ToList(); break;
                    case "Testes": ProjetosFiltrados = ProjetosFiltrados.OrderBy(p => p.Testes).ToList(); break;
                            
                    default: break;
                }
            }
            else
            {
                switch (coluna.DataPropertyName)
                {
                    case "Codigo": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.Codigo).ToList(); break;
                    case "Nome": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.Nome).ToList(); break;
                    case "Regional": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.Regional).ToList(); break;
                    case "Linhas": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.Linhas).ToList(); break;
                    case "Qualidade": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.Qualidade).ToList(); break;
                    case "ConformidadeRegras": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.ConformidadeRegras).ToList(); break;
                    case "Cobertura": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.Cobertura).ToList(); break;
                    case "Violacoes": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.Violacoes).ToList(); break;
                    case "CodigoDuplicado": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.CodigoDuplicado).ToList(); break;
                    case "DebitoTecnico": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.DebitoTecnico).ToList(); break;
                    case "Comentarios": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.Comentarios).ToList(); break;
                    case "SucessoTestes": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.SucessoTestes).ToList(); break;
                    case "ViolacoesBlockerCritical": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.ViolacoesBlockerCritical).ToList(); break;
                    case "Arquitetura": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.Arquitetura).ToList(); break;
                    case "Design": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.Design).ToList(); break;
                    case "Fonte": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.Fonte).ToList(); break;
                    case "Testes": ProjetosFiltrados = ProjetosFiltrados.OrderByDescending(p => p.Testes).ToList(); break;
                    
                    default: break;
                }
            }
            CarregarGrid();
        }

        private void chkRegional_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            FiltraProjetosPorRegional();
            CarregarGrid();
        }

        private void gvProjetos_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (gvProjetos.Columns[e.ColumnIndex].HeaderText.Equals("Detalhes"))
            {
                if (e.RowIndex >= 0)
                {
                    string link = gvProjetos.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
                    System.Diagnostics.Process.Start(link);
                }
            }
        }

        private void rbDetalhada_CheckedChanged(object sender, EventArgs e)
        {
            CarregarGrid();
        }

        private void rbResumida_CheckedChanged(object sender, EventArgs e)
        {
            CarregarGrid();
        }

        private void gvProjetos_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
            {
                if (gbProjetos.Text.Equals("Visão de Evolução no Período"))
                {
                    switch (gvProjetos.Columns[e.ColumnIndex].DataPropertyName)
                    {
                        case "Qualidade":
                        case "ConformidadeRegras":
                        case "Cobertura":
                        case "Comentarios":
                        case "SucessoTestes":
                        case "Arquitetura":
                        case "Design":
                        case "Testes":
                        case "Fonte":
                            float valorCrescente;
                            if (float.TryParse(e.Value.ToString(), out valorCrescente))
                            {
                                if(valorCrescente > 0)
                                {
                                    e.CellStyle.BackColor = Color.PaleGreen;
                                    e.CellStyle.Font = new Font(e.CellStyle.Font, FontStyle.Bold);
                                }
                                else if(valorCrescente < 0)
                                {
                                    e.CellStyle.BackColor = Color.OrangeRed;
                                    e.CellStyle.Font = new Font(e.CellStyle.Font, FontStyle.Bold);
                                }
                            }
                            break;
                        case "Violacoes":
                        case "CodigoDuplicado":
                        case "DebitoTecnico":
                        case "ViolacoesBlockerCritical":
                            float valorDecrescente;
                            if (float.TryParse(e.Value.ToString(), out valorDecrescente))
                            {
                                if (valorDecrescente < 0)
                                {
                                    e.CellStyle.BackColor = Color.PaleGreen;
                                    e.CellStyle.Font = new Font(e.CellStyle.Font, FontStyle.Bold);
                                }
                                else if (valorDecrescente > 0)
                                {
                                    e.CellStyle.BackColor = Color.OrangeRed;
                                    e.CellStyle.Font = new Font(e.CellStyle.Font, FontStyle.Bold);
                                }
                            }
                            break;
                        
                        default:
                            e.CellStyle.BackColor = Color.White;
                            e.CellStyle.Font = new Font(e.CellStyle.Font, FontStyle.Regular);
                            break;
                    }
                }
                else
                {
                    e.CellStyle.BackColor = Color.White;
                }
            }
        }

        private void AgruparProjetosPorRegional()
        {
            ProjetosAgrupados.Clear();
            string parametro = ConfigurationManager.AppSettings["filtros"];
            if (!string.IsNullOrWhiteSpace(parametro))
            {
                foreach (ListViewItem regional in chkRegional.CheckedItems)
                {
                    var filtro = IdentificaFiltro(regional.Text.Trim());
                    var filtrados = ProjetosFiltrados;
                    if (!string.IsNullOrWhiteSpace(filtro))
                    {
                        filtrados = filtrados.Where(p => p.Projeto.Filtros[parametro] == filtro).ToList();
                    }
                    if (filtrados.Count() > 0)
                    {
                        AvaliacaoGrupo avaliacaoRegional = new AvaliacaoGrupo(filtrados, regional.Text.Trim());
                        ProjetosAgrupados.Add(avaliacaoRegional);
                    }
                }
            }
            else
            {
                AvaliacaoGrupo avaliacaoRegional = new AvaliacaoGrupo(ProjetosFiltrados, string.Empty);
                ProjetosAgrupados.Add(avaliacaoRegional);
            }
        }

        private void cbAgrupar_CheckedChanged(object sender, EventArgs e)
        {
            gbProjetos.Text = "Visão Agrupada";
            AgruparProjetosPorRegional();
            CarregarGrid();
        }

        private void btSobre_Click(object sender, EventArgs e)
        {
            frmSobre form = new frmSobre();
            form.ShowDialog();
        }

        private void btLimpar_Click(object sender, EventArgs e)
        {
            FiltraProjetosPorRegional();
        }

    }
}
